package com.example.mqmanager.service;

import com.example.mqmanager.config.DynamicRabbitMQConfig;
import com.example.mqmanager.dto.QueueInfo;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.GetResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Service
public class RabbitMQMonitorService {

    private static final Logger logger = LoggerFactory.getLogger(RabbitMQMonitorService.class);

    @Autowired
    private DynamicRabbitMQConfig dynamicRabbitMQConfig;

    /**
     * 获取所有队列信息
     * 注意：由于AMQP协议限制，无法直接获取所有队列列表
     * 实际项目中可以通过RabbitMQ Management HTTP API获取
     */
    public List<QueueInfo> getAllQueues() {
        // 在实际应用中，应该通过RabbitMQ Management API获取队列列表
        // 这里暂时返回空列表，后续可以通过HTTP API实现
        return new ArrayList<>();
    }

    /**
     * 通过RabbitMQ Management HTTP API获取所有队列
     * 需要在RabbitMQ中启用Management插件
     */
    public List<QueueInfo> getAllQueuesViaHttpApi() {
        List<QueueInfo> queues = new ArrayList<>();
        // 这里应该通过HTTP请求访问RabbitMQ Management API
        // 示例：GET http://localhost:15672/api/queues
        // 但由于需要额外的HTTP客户端依赖和复杂的认证过程，
        // 我们先保持简单实现
        return queues;
    }

    /**
     * 获取指定队列中的消息数量
     *
     * @param queueName 队列名称
     * @return 消息数量
     */
    public long getMessageCount(String queueName) throws IOException {
        return getMessageCount(queueName, dynamicRabbitMQConfig.getVirtualHost());
    }
    
    /**
     * 获取指定队列中的消息数量（指定Virtual Host）
     *
     * @param queueName 队列名称
     * @param virtualHost Virtual Host
     * @return 消息数量
     */
    public long getMessageCount(String queueName, String virtualHost) throws IOException {
        Connection connection = null;
        Channel channel = null;
        
        try {
            ConnectionFactory connectionFactory = dynamicRabbitMQConfig.getConnectionFactory(virtualHost);
            connection = connectionFactory.createConnection();
            channel = connection.createChannel(false);
            
            // 使用passive模式声明队列，不会实际创建队列，但会获取队列信息
            channel.queueDeclarePassive(queueName);
            // 获取队列中的消息数量
            return channel.messageCount(queueName);
        } finally {
            closeResource(channel);
            closeResource(connection);
        }
    }

    /**
     * 获取指定队列的详细信息
     *
     * @param queueName 队列名称
     * @return 队列信息
     */
    public QueueInfo getQueueInfo(String queueName) throws IOException {
        return getQueueInfo(queueName, dynamicRabbitMQConfig.getVirtualHost());
    }
    
    /**
     * 获取指定队列的详细信息（指定Virtual Host）
     *
     * @param queueName 队列名称
     * @param virtualHost Virtual Host
     * @return 队列信息
     */
    public QueueInfo getQueueInfo(String queueName, String virtualHost) throws IOException {
        Connection connection = null;
        Channel channel = null;
        
        try {
            ConnectionFactory connectionFactory = dynamicRabbitMQConfig.getConnectionFactory(virtualHost);
            connection = connectionFactory.createConnection();
            channel = connection.createChannel(false);
            
            // 使用passive模式声明队列，不会实际创建队列，但会获取队列信息
            channel.queueDeclarePassive(queueName);
            // 获取队列中的消息数量
            long messageCount = channel.messageCount(queueName);
            // 获取队列的消费者数量
            long consumerCount = channel.consumerCount(queueName);
            
            return new QueueInfo(queueName, messageCount, consumerCount);
        } finally {
            closeResource(channel);
            closeResource(connection);
        }
    }

    /**
     * 获取队列中的消息内容（仅获取，不消费）
     *
     * @param queueName 队列名称
     * @param count 获取消息数量
     * @return 消息列表
     */
    public List<String> getMessages(String queueName, int count) throws IOException {
        return getMessages(queueName, count, dynamicRabbitMQConfig.getVirtualHost());
    }
    
    /**
     * 获取队列中的消息内容（仅获取，不消费，指定Virtual Host）
     *
     * @param queueName 队列名称
     * @param count 获取消息数量
     * @param virtualHost Virtual Host
     * @return 消息列表
     */
    public List<String> getMessages(String queueName, int count, String virtualHost) throws IOException {
        List<String> messages = new ArrayList<>();
        Connection connection = null;
        Channel channel = null;
        
        try {
            ConnectionFactory connectionFactory = dynamicRabbitMQConfig.getConnectionFactory(virtualHost);
            connection = connectionFactory.createConnection();
            channel = connection.createChannel(false);
            
            // 使用passive模式声明队列
            channel.queueDeclarePassive(queueName);
            
            // 获取指定数量的消息（不消费）
            for (int i = 0; i < count; i++) {
                GetResponse response = channel.basicGet(queueName, false);
                if (response == null) {
                    break;
                }
                
                AMQP.BasicProperties props = response.getProps();
                byte[] body = response.getBody();
                // 使用UTF-8编码确保中文正确显示
                String message = new String(body, StandardCharsets.UTF_8);
                messages.add(message);
                
                // 重新将消息放回队列
                channel.basicNack(response.getEnvelope().getDeliveryTag(), false, true);
            }
        } finally {
            closeResource(channel);
            closeResource(connection);
        }
        
        return messages;
    }
    
    /**
     * 删除队列中的消息
     *
     * @param queueName 队列名称
     * @param count 删除消息的数量
     * @param virtualHost Virtual Host
     * @return 删除的消息数量
     */
    public int removeMessages(String queueName, int count, String virtualHost) throws IOException {
        int removedCount = 0;
        Connection connection = null;
        Channel channel = null;
        
        try {
            ConnectionFactory connectionFactory = dynamicRabbitMQConfig.getConnectionFactory(virtualHost);
            connection = connectionFactory.createConnection();
            channel = connection.createChannel(false);
            
            // 使用passive模式声明队列
            channel.queueDeclarePassive(queueName);
            
            // 获取并删除指定数量的消息
            for (int i = 0; i < count; i++) {
                GetResponse response = channel.basicGet(queueName, true); // true表示自动确认消费
                if (response == null) {
                    break;
                }
                removedCount++;
            }
        } finally {
            closeResource(channel);
            closeResource(connection);
        }
        
        return removedCount;
    }
    
    /**
     * 删除队列中的单条消息
     *
     * @param queueName 队列名称
     * @param virtualHost Virtual Host
     * @return 是否删除成功
     */
    public boolean removeSingleMessage(String queueName, String virtualHost) throws IOException {
        Connection connection = null;
        Channel channel = null;
        
        try {
            ConnectionFactory connectionFactory = dynamicRabbitMQConfig.getConnectionFactory(virtualHost);
            connection = connectionFactory.createConnection();
            channel = connection.createChannel(false);
            
            // 使用passive模式声明队列
            channel.queueDeclarePassive(queueName);
            
            // 获取并删除一条消息
            GetResponse response = channel.basicGet(queueName, true); // true表示自动确认消费
            return response != null;
        } finally {
            closeResource(channel);
            closeResource(connection);
        }
    }
    
    /**
     * 安全关闭资源
     */
    private void closeResource(AutoCloseable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (Exception e) {
                logger.warn("关闭资源时出错: " + e.getMessage());
            }
        }
    }
    
    /**
     * 更新RabbitMQ配置
     */
    public void updateRabbitMQConfig(String host, int port, String username, String password, String virtualHost) {
        dynamicRabbitMQConfig.setHost(host);
        dynamicRabbitMQConfig.setPort(port);
        dynamicRabbitMQConfig.setUsername(username);
        dynamicRabbitMQConfig.setPassword(password);
        dynamicRabbitMQConfig.setVirtualHost(virtualHost);
    }
}